
package cfar.parallel.map;

import cfar.ff.data.Stream;
import cfar.ff.fun.F1;
import cfar.ff.fun.F2;
import cfar.ff.fun.Seq;
import cfar.ff.interfaces.Empty;
import cfar.ff.interfaces.Sequence;

import static cfar.ff.fun.Seq.*;

import static fj.control.parallel.Strategy.*;


/**
 *
 * @author badi
 */
public class Map<S,A,B> implements F2<F1<A,B>, Sequence<S,A>, Sequence<S,B>> {

    public Sequence<S, B> f(F1<A,B> f, Sequence<S, A> seq) {
        // no redundancy
        Sequence<Stream, Integer> red = Stream.<Integer>nil();
        for(int i = 0; i < length(seq); i++)
            red = red.snoc(1);

        // choose first
        F1<Sequence<Stream,A>, A> choose = new F1<Sequence<Stream, A>, A>() {

            public A f(Sequence<Stream, A> s) {
                return s.head();
            }
        };


        return new RMap().f(choose, red, f, seq);
    }

    public Sequence<S, B> old(F1<A,B> f, Sequence<S, A> seq) {
        fj.data.List<A> l = Seq.mkList(seq).getList();
        fj.data.List<B> os = (fj.data.List<B>) simpleThreadStrategy().parMap((F1)f, l)._1();

        return mkSeq(os, (Sequence<S,B>) seq.<B>empty());
    }

}
